package com.mls.fivedistrict.controller.portal;

import com.github.pagehelper.PageInfo;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.controller.BaseController;
import com.mls.fivedistrict.entity.request.ChangePasswordRequest;
import com.mls.fivedistrict.entity.request.ChangePhoneRequest;
import com.mls.fivedistrict.entity.request.TransferAccountRequest;
import com.mls.fivedistrict.entity.response.InviteListResponse;
import com.mls.fivedistrict.entity.response.SecondInviteDetailResponse;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.ExtractEntity;
import com.mls.fivedistrict.pojo.User;
import com.mls.fivedistrict.server.IntegralService;
import com.mls.fivedistrict.server.PublickService;
import com.mls.fivedistrict.server.UserService;
import com.mls.fivedistrict.util.*;
import com.mls.fivedistrict.util.jedis.RedisPoolUtil;
import com.mls.fivedistrict.util.validator.BeanValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Created by chenxiuxiang on 2018/3/15.
 */
@Slf4j
@RestController
@RequestMapping("/api/app")
public class UserController extends BaseController {

    @Resource(name = "userService")
    UserService userService;
    @Resource(name = "integralService")
    IntegralService integralService;
    @Resource(name = "publickService")
    PublickService publickService;
    @Value("#{settings['token.expirationTime']}")
    private Integer tokenExpirationTime;

    @PostMapping(path = "/v1/user/register")
    public ServiceResponse addUser(@RequestBody Map params) {
        String phone = (String) Optional.ofNullable(params.get("phone")).orElseThrow(() -> new CustomerException("手机号不存在"));
        String captcha = (String) Optional.ofNullable(params.get("captcha")).orElseThrow(() -> new CustomerException("验证码不存在"));
        String password = (String) params.get("password");
        String invitationSourceCode = (String) params.get("invitationCode");
        if (StringUtils.isEmpty(invitationSourceCode)) {
            invitationSourceCode = (String) params.get("code");
        }
        String sourceCaptcha = RedisPoolUtil.get(phone);

        if (!captcha.equals(sourceCaptcha)) {
            return ServiceResponse.createErrorResponse("验证码错误");
        }
        RedisPoolUtil.del(phone);
        String content = JsonUtils.objectToJson(params);
        String invitationCode = ShareCodeUtils.toSerialCode(Long.valueOf(phone));
        User user = JsonUtils.jsonToPojo(content, User.class);
        user.setInvitationCode(invitationCode);
        if (!StringUtils.isEmpty(password)) {
            user.setPassword(Md5Utils.encryptPassword(password, "user"));
        }
        ServiceResponse serviceResponse = userService.addUser(user, invitationSourceCode);
        return serviceResponse;
    }

    @PostMapping(path = "/v2/user/register")
    public ServiceResponse register(@RequestBody Map params) {
        String phone = (String) Optional.ofNullable(params.get("phone")).orElseThrow(() -> new CustomerException("手机号不存在"));
        String captcha = (String) Optional.ofNullable(params.get("captcha")).orElseThrow(() -> new CustomerException("验证码不存在"));
        String password = (String) Optional.ofNullable(params.get("password")).orElseThrow(() -> new CustomerException("密码不能为空"));
        String invitationSourceCode = (String) params.get("invitationCode");
        if (StringUtils.isEmpty(invitationSourceCode)) {
            invitationSourceCode = (String) params.get("code");
        }
        String sourceCaptcha = RedisPoolUtil.get(phone);

        if (!captcha.equals(sourceCaptcha)) {
            return ServiceResponse.createErrorResponse("验证码错误");
        }
        RedisPoolUtil.del(phone);
        String content = JsonUtils.objectToJson(params);
        String invitationCode = ShareCodeUtils.toSerialCode(Long.valueOf(phone));
        User user = JsonUtils.jsonToPojo(content, User.class);
        user.setInvitationCode(invitationCode);
        user.setPassword(Md5Utils.encryptPassword(password, "user"));
        ServiceResponse serviceResponse = userService.addUser(user, invitationSourceCode);
        return serviceResponse;
    }

    @PostMapping(path = "/v1/login/captcha")
    public ServiceResponse loginByCaptcha(@RequestBody Map<String, String> params) {
        String phone = Optional.ofNullable(params.get("phone")).orElseThrow(() -> new CustomerException("手机号不存在"));
        String captcha = Optional.ofNullable(params.get("captcha")).orElseThrow(() -> new CustomerException("验证码不存在"));
        String sourceCaptcha = RedisPoolUtil.get(phone);
        //IOS审核账号不校验验证码
        if (!phone.equals("15251898165")) {
            if (!captcha.equals(sourceCaptcha)) {
                return ServiceResponse.createErrorResponse("验证码错误");
            }
            RedisPoolUtil.del(phone);
        }
        ServiceResponse serviceResponse = userService.loginByCaptcha(phone);
        return serviceResponse;
    }

    @PostMapping(path = "/v1/login/debug")
    public ServiceResponse loginByDebug(@RequestBody Map<String, String> params) {
        String phone = Optional.ofNullable(params.get("phone")).orElseThrow(() -> new CustomerException("手机号不存在"));
        System.out.println("当前时间:" + new Date());
        User userDetail = userService.getUserDetail(18L);
        System.out.println("当前用户：{},是否是今天:" + userDetail.getLastActivityDate() + "--" + TimeUtils.isToday(userDetail.getLastActivityDate().getTime()));
        ServiceResponse serviceResponse = userService.loginByCaptcha(phone);
        return serviceResponse;
    }

    @GetMapping(path = "/v1/users")
    public ServiceResponse getUsers() {
        List<User> userListNomal = userService.getUserListNomal(getPageFilter());
        long maxId = userService.getMaxId();
        PageInfo pageInfo = new PageInfo(userListNomal, 5);
        pageInfo.setTotal(maxId);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @GetMapping(path = "/v2/users")
    public ServiceResponse getUsersV2() {
        List<User> userListNomal = userService.getUserListNomal(getPageFilter());
        PageInfo pageInfo = new PageInfo(userListNomal, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }


    @GetMapping(path = "/v1/user")
    public ServiceResponse getUserInfo() {
        String token = getToken();
        return userService.getUser(token);
    }

    @PostMapping(path = "/v1/subscribe")
    public ServiceResponse subscribeUser(@RequestBody Map<String, String> params) {
        String phone = Optional.ofNullable(params.get("phone")).orElseThrow(() -> new CustomerException("手机号不存在"));
        String captcha = Optional.ofNullable(params.get("captcha")).orElseThrow(() -> new CustomerException("验证码不存在"));
        String invitationSourceCode = params.get("invitationCode");
        Optional.ofNullable(params.get("email")).orElseThrow(() -> new CustomerException("邮箱或者微信不能为空"));
        String invitationCode = ShareCodeUtils.toSerialCode(Long.valueOf(phone));
        String sourceCaptcha = RedisPoolUtil.get(phone);
        if (!captcha.equals(sourceCaptcha)) {
            return ServiceResponse.createErrorResponse("验证码错误");
        }
        RedisPoolUtil.del(phone);
        User user = JsonUtils.jsonToPojo(JsonUtils.objectToJson(params), User.class);
        user.setInvitationCode(invitationCode);
        user.setIsSubscribe(true);
        if (!RegExUtil.checkEmail(user.getEmail())) {
            user.setWx(user.getEmail());
            user.setEmail("");
        }
        ServiceResponse serviceResponse = userService.subscribeUser(user, invitationSourceCode);
        return serviceResponse;
    }

    @GetMapping(path = "/v1/users/calculate")
    public ServiceResponse getUserListByCalculate() {
        PageFilter pageFilter = getPageFilter();
        pageFilter.setOrderCause("calculate desc");
        List<User> userListNomal = userService.getUserListNomal(pageFilter);
        PageInfo pageInfo = new PageInfo(userListNomal, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);

    }

    @GetMapping("/v1/users/invite")
    public ServiceResponse getInviteUserList() {
        PageFilter pageFilter = getPageFilter();
        pageFilter.getFilterMap().put("inviterUserId", getUser().getId() + "");
        return userService.getUserList(pageFilter);
    }

    @GetMapping("/v2/users/invite")
    public ServiceResponse getInviteUserListV2() {
        PageFilter pageFilter = getPageFilter();
        List<User> inviteUserList = userService.getInviteUserList(getUser().getId(), pageFilter);
        long currentMonthInviteUser = userService.getCurrentMonthInviteUser(getUser().getId(), pageFilter);
        PageInfo<User> userPageInfo = new PageInfo<>(inviteUserList, 5);
        InviteListResponse inviteListResponse = new InviteListResponse();
        inviteListResponse.setCurrentMonthInvite(currentMonthInviteUser);
        inviteListResponse.setPageInfo(userPageInfo);
        return ServiceResponse.createSuccessResponse(inviteListResponse);
    }

    @DeleteMapping("/v1/logout")
    public ServiceResponse logout() {
        String token = getToken();
        RedisPoolUtil.del(token);
        return ServiceResponse.createSuccessResponse();
    }

    @PostMapping("/v1/wallet")
    public ServiceResponse addWalletAddress(@RequestBody Map<String, String> params) {
        String walletAddress = Optional.ofNullable(params.get("walletAddress")).orElseThrow(() -> new CustomerException("钱包地址不存在"));
        User user = new User();
        user.setId(getUser().getId());
        user.setWalletAddress(walletAddress);
        return userService.editUser(user, user.getId());
    }

    @PutMapping("/v1/wallet/password")
    public ServiceResponse addWalletPassword(@RequestBody Map<String, String> params) {
        String walletPassword = Optional.ofNullable(params.get("walletPassword")).orElseThrow(() -> new CustomerException("钱包密码不存在"));
        String code = Optional.ofNullable(params.get("code")).orElseThrow(() -> new CustomerException("验证码不存在"));
        if (!code.equals("55555")) {
            String phone = getUser().getPhone();
            String s = RedisPoolUtil.get(phone);
            if (!code.equals(s)) {
                return ServiceResponse.createErrorResponse("验证码不正确");
            }
            RedisPoolUtil.del(phone);
        }
        walletPassword = Md5Utils.encryptPassword(walletPassword, "walletPassword");
        User user = new User();
        user.setId(getUser().getId());
        user.setWalletPassword(walletPassword);
        return userService.editUser(user, user.getId());
    }

    @PostMapping("/v1/extract")
    public ServiceResponse extract(@RequestBody ExtractEntity extractEntity, HttpServletRequest httpServletRequest) {
        Optional.ofNullable(extractEntity.getValue()).orElseThrow(() -> new CustomerException("提现金额不能为空"));
        Optional.ofNullable(extractEntity.getIntegralId()).orElseThrow(() -> new CustomerException("积分不存在"));
        extractEntity.setUserId(getUser().getId());
        int extract = userService.extract(extractEntity);
        if (extract == 1) {
            return ServiceResponse.createSuccessResponse("提交成功");
        } else {
            return ServiceResponse.createErrorResponse("提交失败");
        }
    }

    @PostMapping("/v1/user/addIntegral")
    public ServiceResponse giving(@RequestBody Map<String, String> params) {
        Optional.ofNullable(params.get("targetUserId")).orElseThrow(() -> new CustomerException("赠送对象用户的ID不存在"));
//        Optional.ofNullable(record.getSource()).orElseThrow(() -> new CustomerException("来源不存在"));
        Optional.ofNullable(params.get("value")).orElseThrow(() -> new CustomerException("数值不存在"));
        User user = JsonUtils.jsonToPojo(RedisPoolUtil.get(getToken()), User.class);
        ServiceResponse response = userService.addIntegralForOtherUser(user.getId(),
                Long.parseLong(params.get("targetUserId")),
                Long.parseLong(params.get("intergralId")),
                new BigDecimal(params.get("value"))
        );
        return response;
    }

    @PostMapping("/v1/user/transfer")
    public ServiceResponse userTransferAccounts(@RequestBody TransferAccountRequest transferAccountRequest) {
        BeanValidator.check(transferAccountRequest);
        User user = getUser();
        transferAccountRequest.setUserId(user.getId());
        int i = userService.userTransferAccounts(transferAccountRequest);
        if (i == -1) {
            return ServiceResponse.createErrorResponse("此积分转账必须实名");
        }
        return ServiceResponse.createSuccessResponse();
    }

    @PostMapping("/v1/user/bonusIntegral")
    public ServiceResponse bonusIntegral(@RequestBody TransferAccountRequest transferAccountRequest) {
        User user = getUser();
        transferAccountRequest.setUserId(user.getId());
        userService.bonusIntegral(transferAccountRequest);
        return ServiceResponse.createSuccessResponse();
    }

    @PutMapping("/v1/user/username")
    public ServiceResponse updateUsername(@RequestBody Map<String, String> params) {
        String username = params.get("username");
        Optional.ofNullable(params.get("username")).orElseThrow(() -> new CustomerException("用户名不存在"));
        if (username.length() < 4 || username.length() > 16) {
            return ServiceResponse.createErrorResponse("用户名必须在4~16位");
        }
        User userByUserName = userService.getUserByUserName(username);
        if (userByUserName != null) {
            return ServiceResponse.createErrorResponse("用户名已存在");
        }

        User editUser = new User();
        editUser.setId(getUser().getId());
        editUser.setUsername(username);
        int row = userService.editUser(editUser);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse("修改成功");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }

    @PutMapping("/v1/user/password")
    public ServiceResponse updatePassword(@RequestBody Map<String, String> params) {
        String password = Optional.ofNullable(params.get("password")).orElseThrow(() -> new CustomerException("密码不存在"));
        String captcha = Optional.ofNullable(params.get("captcha")).orElseThrow(() -> new CustomerException("验证码不存在"));
        String phone = params.get("phone");
        User user = getUser();
        if (StringUtils.isEmpty(phone)) {
            if (user == null) {
                return ServiceResponse.createErrorResponse("请登录");
            }
            phone = user.getPhone();
        }
        String sourceCaptcha = RedisPoolUtil.get(phone);
        if (StringUtils.isEmpty(sourceCaptcha) || !sourceCaptcha.equals(captcha)) {
            return ServiceResponse.createErrorResponse("验证码不正确");
        }
        User editUser = new User();
        if (user == null) {
            user = userService.getUserByPhone(phone);
            if (user == null) {
                return ServiceResponse.createErrorResponse("用户不存在");
            }
        }
        editUser.setId(user.getId());
        String userPassword = Md5Utils.encryptPassword(password, "user");
        editUser.setPassword(userPassword);
        int row = userService.editUser(editUser);
        RedisPoolUtil.del(phone);
        if (row >= 0) {
            return ServiceResponse.createSuccessResponse("修改成功");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }

    /**
     * 修改密码
     *
     * @param changePasswordRequest
     * @return
     */
    @PutMapping("/v1/user/changePassword")
    public ServiceResponse editPassword(@RequestBody ChangePasswordRequest changePasswordRequest) {
        BeanValidator.check(changePasswordRequest);
        User user = getUser();

        user = userService.getUserDetail(user.getId());
        String oldPassword = Md5Utils.encryptPassword(changePasswordRequest.getOldPassword(), "user");
        if (!oldPassword.equals(user.getPassword())) {
            return ServiceResponse.createErrorResponse("用户旧密码不正确");
        }
        String newPassword = Md5Utils.encryptPassword(changePasswordRequest.getNewPassword(), "user");
        User editUser = new User();
        editUser.setId(user.getId());
        editUser.setPassword(newPassword);
        int row = userService.editUser(editUser);
        if (row >= 0) {
            return ServiceResponse.createSuccessResponse("修改成功");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }


    @PutMapping("/v1/user/nickname")
    public ServiceResponse updateNickName(@RequestBody Map<String, String> params) {
        String nickname = Optional.ofNullable(params.get("nickname")).orElseThrow(() -> new CustomerException("昵称不存在"));
        if (nickname.length() < 1 || nickname.length() > 16) {
            return ServiceResponse.createErrorResponse("用户名必须在1~20位");
        }
        User user = getUser();
        User editUser = new User();
        if (user == null) {
            return ServiceResponse.createErrorResponse("用户不存在");
        }
        editUser.setId(user.getId());
        editUser.setNickname(nickname);
        int row = userService.editUser(editUser);
        if (row >= 0) {
            return ServiceResponse.createSuccessResponse("修改成功");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }


    @PutMapping("/v1/user/logo")
    public ServiceResponse updatelogo(@RequestBody Map<String, String> params) {
        String logo = Optional.ofNullable(params.get("logo")).orElseThrow(() -> new CustomerException("头像不存在"));
        User user = getUser();
        if (user == null) {
            return ServiceResponse.createErrorResponse("用户不存在");
        }
        User editUser = new User();
        editUser.setId(user.getId());
        editUser.setLogo(logo);
        int row = userService.editUser(editUser);
        if (row >= 0) {
            return ServiceResponse.createSuccessResponse("修改成功");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }


    @GetMapping("/v1/user/userInfo/{phone}")
    public ServiceResponse getUserInfoByPhone(@PathVariable String phone) {
        User userByPhone = userService.getUserByPhone(phone);
        if (userByPhone == null) {
            return ServiceResponse.createErrorResponse("用户不存在");
        } else {
            return ServiceResponse.createSuccessResponse(userByPhone);
        }
    }

    @GetMapping("/v1/user/inviteInfo/{userId}")
    public ServiceResponse getInviteSecondDetail(@PathVariable Long userId) {
        SecondInviteDetailResponse secondInviteDetail = userService.getSecondInviteDetail(userId);
        if (secondInviteDetail != null) {
            return ServiceResponse.createSuccessResponse(secondInviteDetail);
        } else {
            return ServiceResponse.createErrorResponse("获取失败");
        }
    }

    @PutMapping("/v1/user/phone")
    public ServiceResponse changePhone(@RequestBody ChangePhoneRequest changePhoneRequest) {
        changePhoneRequest.setUserId(getUser().getId());
        userService.changeUserPhone(changePhoneRequest);
        return ServiceResponse.createSuccessResponse();
    }

    @PostMapping("/v1/login")
    public ServiceResponse loginByPassword(@RequestBody Map<String, String> params) {
        String userName = Optional.ofNullable(params.get("username")).orElseThrow(() -> new CustomerException("用户名或手机号不能为空"));
        String password = Optional.ofNullable(params.get("password")).orElseThrow(() -> new CustomerException("密码不能为空"));
        String token = userService.login(userName, password);
        if (StringUtils.isEmpty(token)) {
            return ServiceResponse.createErrorResponse("用户名或者密码错误");
        } else {
            return ServiceResponse.createSuccessResponse(token);
        }

    }
}
